package com.sangeng.service.impl;


import ch.qos.logback.core.joran.conditional.IfAction;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sangeng.domain.ResponseResult;
import com.sangeng.domain.constants.SystemConstants;
import com.sangeng.domain.entity.Menu;
import com.sangeng.domain.entity.RoleMenu;
import com.sangeng.domain.vo.ChangeRoleMenuVo;
import com.sangeng.domain.vo.MenuVo;
import com.sangeng.domain.vo.RoleMenuVo;
import com.sangeng.enums.AppHttpCodeEnum;
import com.sangeng.handler.exception.SystemException;
import com.sangeng.mapper.MenuMapper;
import com.sangeng.service.MenuService;
import com.sangeng.service.RoleMenuService;
import com.sangeng.utils.BeanCopyUtils;
import com.sangeng.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author makejava
 * @since 2024-08-21 23:20:54
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

   @Autowired
   private MenuService menuService;
   @Autowired
   private  RoleMenuService roleMenuService;
    //根据当前用户id查询权限信息
    @Override
    public List<String> selectPermsByUserId(Long id) {
        //id=1说明是管理员，返回所有权限
        if (id==1L){
            LambdaQueryWrapper<Menu> lambdaQueryWrapper=new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(Menu::getMenuType,SystemConstants.MENU,SystemConstants.BUTTON);
            lambdaQueryWrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMAL);
            List<Menu> menus = list(lambdaQueryWrapper);
            List<String> perms = menus.stream()
                    .map(Menu::getPerms)
                    .collect(Collectors.toList());
            return perms;
        }
        //否则返回所具有的权限
        return getBaseMapper().selectPermsByUserId(id);
    }

    @Override
    public List<MenuVo> selectRoutersMenusByUserId(Long userId) {
        MenuMapper baseMapper = getBaseMapper();
        List<Menu> menus=null;
        //如果是管理员返回所有路由
        if (SecurityUtils.isAdmin()){
             menus=baseMapper.selectAllRouters();
        }else{
            //如果不是管理员就用自定义方法
             menus =baseMapper.selectRouterMenuTreeByUserId(userId);
        }

        //将Menu 转成MenuVo
        List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(menus, MenuVo.class);
        //构建tree 处理
        return buildMenuTree(menuVos, 0L);

    }

    private List<MenuVo> buildMenuTree(List<MenuVo> menuVos, long parentId) {
        //处理信息
      return   menuVos.stream()
                .filter(menuVo -> menuVo.getParentId().equals(parentId))
                .map(menuVo -> menuVo.setChildren(getChildren(menuVo ,menuVos)))
                .collect(Collectors.toList());

    }

    /**
     * 获取存入参数的 子Menu集合
     * @param menuVo
     * @param menuVos
     * @return
     */
    private List<MenuVo> getChildren(MenuVo menuVo , List<MenuVo> menuVos){
        return   menuVos.stream()
                .filter(m -> m.getParentId().equals(menuVo.getId()))
                .map(m-> m.setChildren(getChildren(m,menuVos)))
                .collect(Collectors.toList());

    }

    @Override
    public ResponseResult getList(String status, String menuName) {
        LambdaQueryWrapper<Menu> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StringUtils.hasText(status), Menu::getStatus,status)
                .eq(StringUtils.hasText(menuName), Menu::getMenuName,menuName);
        List<Menu> list = list(lambdaQueryWrapper);

        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult addMenu(Menu menu) {
        save(menu);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult updateMenu(Menu menu) {
        //修改的时候不能把父菜单(parentId)设置为当前菜单(id)，如果设置了需要给出相应的提示。并且修改失败。
        if (menu.getId().equals(menu.getParentId())){
            throw new RuntimeException("修改菜单"+menu.getMenuName()+"失败，上级菜单不能选择自己");
        }
        updateById(menu);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteByMenuId(Long menuId) {
        //能够删除菜单，但是如果要删除的菜单有子菜单则提示：存在子菜单不允许删除 并且删除失败。
        // 根据parentId进行查询如果count》0说明有子菜单
        LambdaQueryWrapper<Menu> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Menu::getParentId,menuId);
        int count = count(lambdaQueryWrapper);
        if (count>0){
            throw  new SystemException(AppHttpCodeEnum.MENU_NOT_DELETE);
        }
        removeById(menuId);
        return ResponseResult.okResult();
    }

    @Override
    public List<RoleMenuVo> treeSelect() {
        List<Menu> menuList = menuService.list();
        //转化
        List<RoleMenuVo> menuVos = BeanCopyUtils.copyBeanList(menuList, RoleMenuVo.class);
        //将menuList的menu.name手动复制给roleMenuVos.menu.lable
        for (RoleMenuVo roleMenuVo : menuVos) {
            for (Menu menu : menuList) {
                if (menu.getId()==roleMenuVo.getId()){
                    roleMenuVo.setLabel(menu.getMenuName());
                    break;
                }
            }
        }

        //构造树
        List<RoleMenuVo> menuVos1 = menuVos.stream()
                .filter(menuVo -> menuVo.getParentId().equals(0L))
                .map(menuVo -> menuVo.setChildren(getRoleChildren(menuVo, menuVos)))
                .collect(Collectors.toList());

        return menuVos1;
    }

    private List<RoleMenuVo> getRoleChildren(RoleMenuVo menuVo, List<RoleMenuVo> menuVos) {
        return menuVos.stream()
                .filter(m-> m.getParentId().equals(menuVo.getId()))
                .map(m->m.setChildren(getRoleChildren(m,menuVos)))
                .collect(Collectors.toList());
    }

    @Override
    public ResponseResult roleMenuTreeSelect(Long id) {
        //获取菜单树
        List<RoleMenuVo> roleMenuVos = treeSelect();
        //通过角色id获取菜单id
        LambdaQueryWrapper<RoleMenu> lQW=new LambdaQueryWrapper<>();
        lQW.eq(RoleMenu::getRoleId,id);
        List<RoleMenu> list = roleMenuService.list(lQW);
        List<Long> checkedKeys = list
                .stream()
                .map(RoleMenu::getMenuId).collect(Collectors.toList());
        ChangeRoleMenuVo changeRoleMenuVo=new ChangeRoleMenuVo();
        changeRoleMenuVo.setMenus(roleMenuVos);
        changeRoleMenuVo.setCheckedKeys(checkedKeys);
        return ResponseResult.okResult(changeRoleMenuVo);
    }
}
